/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package lc3vm;


public class Interpretador {

    public static boolean primera = true;

    public static void ejecutar(String linea) {

        //Contendrá el número del registro de destino y fuentes
        int dR, sR1, sR2, resultado, opcode, direccionDec;
        String instruccion = null;
        boolean salto = false;

        //Se convierten los 4 digitos del opcode a decimal, para facilitar
        //las comparaciones de las condiciones
        opcode = Convertidor.binInt(linea.substring(0,4));
        System.out.println(opcode);
               System.out.println(linea.substring(0,4));
       if(primera) {
            Memoria.setDirActual(Convertidor.binInt(linea));
            primera = false;
       }


        //Condiciones de opcode
        switch(opcode) {

            case 0: //Es BR
                int opcion = Convertidor.binInt(linea.substring(4, 7));

                switch(opcion){
                    case 1://es positivo
                        if(Registros.getR(Registros.getUltimoR()) > 0)
                            salto = true;
                        //else
                          //aquiva la instruccion de aumentar dir
                    break;

                    case 2://es cero
                        if (Registros.getR(Registros.getUltimoR()) == 0)
                            salto = true;
                    break;

                    case 3:// es positivo o cero
                        if ((Registros.getR(Registros.getUltimoR()) > 0) || (Registros.getR(Registros.getUltimoR()) == 0))
                            salto = true;
                    break;

                    case 4://es negativo
                        if(Registros.getR(Registros.getUltimoR()) < 0)
                            salto = true;
                    break;

                    case 5://es negativo o positivo
                        if((Registros.getR(Registros.getUltimoR()) < 0) || (Registros.getR(Registros.getUltimoR()) > 0))
                            salto = true;
                    break;

                    case 6://es negativo o cero
                        if((Registros.getR(Registros.getUltimoR()) < 0) || (Registros.getR(Registros.getUltimoR()) == 0))
                            salto = true;
                    break;

                    case 7:
                            salto = true;
                    break;

                    default:
                        System.out.println("No existe esta opcion en BR");

                }
                if(salto)
                    Memoria.setDirActual(Convertidor.binC2Int(linea.substring(7)));
                salto = false;
             break;

            //ADD
            case 1:
                //Se asignan los registros de destino y fuentes
                dR = Convertidor.binInt(linea.substring(4, 7));
                sR1 = Convertidor.binInt(linea.substring(7, 10));
                sR2 = Convertidor.binInt(linea.substring(13, 16));

                //Compara el 5to bit, el cual indica si la suma es con operando
                //registro o inmediato
                if(linea.charAt(10) == '0')
                    resultado = Registros.getR(sR1) + Registros.getR(sR2);
                else
                    resultado = Registros.getR(sR1) + Convertidor.binC2Int(linea.substring(11));
                Registros.setR(dR, resultado);

            break;

            //LD
            case 2:

                dR = Convertidor.binInt(linea.substring(4, 7));
                System.out.println(""+ Memoria.getLinea(Convertidor.binHex(linea.substring(7))).getDireccionDec()+" direccion");
                System.out.println(Memoria.getDirActualDec()+" direccion actuaaaaaaaaaaaaaaaaaaaaaaaaal");
                direccionDec = Memoria.getLinea(Convertidor.binHex(linea.substring(7))).getDireccionDec() + Memoria.getDirActualDec();
                System.out.println(direccionDec+" Direccionsssssssssss");
                for(int i = 0; i < Memoria.getCantLineas(); i++)
                    if(Memoria.getLinea(i).getDireccionDec() == direccionDec)
                        instruccion = Memoria.getLinea(i).getInstruccion();

//                System.out.println(instruccion+"  Aquiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
                resultado = Convertidor.binC2Int(instruccion);


                Registros.setR(dR, resultado);

            break;

            //ST
            case 3:

                dR = Convertidor.binInt(linea.substring(4, 7));
                System.out.println(linea);
                System.out.println(Memoria.getLinea(Convertidor.binHex(linea.substring(7))));
                direccionDec = Memoria.getLinea(Convertidor.binHex(linea.substring(7))).getDireccionDec() + Memoria.getDirActualDec();
                for(int i = 0; i < Memoria.getCantLineas(); i++)
                    if(Memoria.getLinea(i).getDireccionDec() == direccionDec) {
                        instruccion = Integer.toBinaryString(Registros.getR(dR));
                        Memoria.getLinea(i).setInstruccion(instruccion);
                    }

            break;

            //SUB (Resta)
            case 4:

                //Se asignan los registros de destino y fuentes
                dR = Convertidor.binInt(linea.substring(4, 7));
                sR1 = Convertidor.binInt(linea.substring(7, 10));
                sR2 = Convertidor.binInt(linea.substring(13, 16));

                //Compara el 5to bit, el cual indica si la resta es con operando
                //registro o inmediato
                if(linea.charAt(10) == '0')
                    resultado = Registros.getR(sR1) - Registros.getR(sR2);
                else
                    resultado = Registros.getR(sR1) - Convertidor.binC2Int(linea.substring(11));
                Registros.setR(dR, resultado);

            break;

            //AND
            case 5:
                //Se asignan los registros de destino y fuentes
                dR = Convertidor.binInt(linea.substring(4, 7));
                sR1 = Convertidor.binInt(linea.substring(7, 10));
                sR2 = Convertidor.binInt(linea.substring(13, 16));

                //Compara el 5to bit, el cual indica si el AND es con operando
                //registro o inmediato
                if(linea.charAt(10) == '0')
                    resultado = Registros.getR(sR1) & Registros.getR(sR2);
                else
                    resultado = Registros.getR(sR1) & Convertidor.binC2Int(linea.substring(11));
                Registros.setR(dR, resultado);

            break;

            //LDR
            case 6:

                dR = Convertidor.binInt(linea.substring(4, 7));
                sR1 = Convertidor.binInt(linea.substring(7, 10));
                direccionDec = Memoria.getLinea(linea.substring(10)).getDireccionDec() + sR1;
                for(int i = 0; i < Memoria.getCantLineas(); i++)
                    if(Memoria.getLinea(i).getDireccionDec() == direccionDec)
                        instruccion = Memoria.getLinea(i).getInstruccion();

                resultado = Convertidor.binC2Int(instruccion);


                Registros.setR(dR, resultado);

            break;

            //STR
            case 7:

                dR = Convertidor.binInt(linea.substring(4, 7));
                sR1 = Convertidor.binInt(linea.substring(7,10));
                direccionDec = Memoria.getLinea(linea.substring(7)).getDireccionDec() + sR1;
                for(int i = 0; i < Memoria.getCantLineas(); i++)
                    if(Memoria.getLinea(i).getDireccionDec() == direccionDec) {
                        instruccion = Integer.toBinaryString(Registros.getR(dR));
                        Memoria.getLinea(i).setInstruccion(instruccion);
                    }
            break;

            //MUL (Multiplicación)
            case 8:
                //Se asignan los registros de destino y fuentes
                dR = Convertidor.binInt(linea.substring(4, 7));
                sR1 = Convertidor.binInt(linea.substring(7, 10));
                sR2 = Convertidor.binInt(linea.substring(13, 16));

                //Compara el 5to bit, el cual indica si la suma es con operando
                //registro o inmediato
                if(linea.charAt(10) == '0')
                    resultado = Registros.getR(sR1) * Registros.getR(sR2);
                else
                    resultado = Registros.getR(sR1) * Convertidor.binC2Int(linea.substring(11));
                Registros.setR(dR, resultado);

            break;

            //NOT
            case 9:
                
                dR = Convertidor.binInt(linea.substring(4, 7));
                sR1 = Convertidor.binInt(linea.substring(7, 10));

                resultado = ~Registros.getR(sR1);

                Registros.setR(dR, resultado);

            break;

            //LDI
            case 10:

                dR = Convertidor.binInt(linea.substring(4, 7));
                direccionDec = Memoria.getLinea(linea.substring(7)).getDireccionDec() + Memoria.getDirActualDec();
                direccionDec = direccionDec + (Convertidor.binC2Int(Memoria.getLinea(direccionDec).getInstruccion()));
                for(int i = 0; i < Memoria.getCantLineas(); i++)
                    if(Memoria.getLinea(i).getDireccionDec() == direccionDec)
                        instruccion = Memoria.getLinea(i).getInstruccion();

                resultado = Convertidor.binInt(instruccion);


                Registros.setR(dR, resultado);

            break;

            //STI
            case 11:

                dR = Convertidor.binInt(linea.substring(4, 7));
                direccionDec = Memoria.getLinea(linea.substring(7)).getDireccionDec() + Memoria.getDirActualDec();
                direccionDec = direccionDec + Convertidor.binC2Int(Memoria.getLinea(direccionDec).getInstruccion());
                for(int i = 0; i < Memoria.getCantLineas(); i++)
                    if(Memoria.getLinea(i).getDireccionDec() == direccionDec) {
                        instruccion = Integer.toBinaryString(Registros.getR(dR));
                        Memoria.getLinea(i).setInstruccion(instruccion);
                    }

            break;

            //JMP
            case 12:

                sR1 = Convertidor.binInt(linea.substring(4, 7));

                direccionDec = Registros.getR(sR1);
                Memoria.setDirActual(direccionDec);

            break;

            //DIV (División)
            case 13:
                //Se asignan los registros de destino y fuentes
                dR = Convertidor.binInt(linea.substring(4, 7));
                sR1 = Convertidor.binInt(linea.substring(7, 10));
                sR2 = Convertidor.binInt(linea.substring(13, 16));

                //Compara el 5to bit, el cual indica si la división es con operando
                //registro o inmediato
                if(linea.charAt(10) == '0')
                    resultado = (int)(Registros.getR(sR1) / Registros.getR(sR2));
                else
                    resultado = (int)(Registros.getR(sR1) / Convertidor.binC2Int(linea.substring(11)));
                Registros.setR(dR, resultado);
                
            break;

            //LEA
            case 14:

                dR = Convertidor.binInt(linea.substring(4, 7));
                resultado = Memoria.getDirActualDec() + Convertidor.binC2Int(linea.substring(7));

                Registros.setR(dR, resultado);

            break;

            //TRAP
            case 15:

                boolean espera = true;

                direccionDec = Memoria.getDirActualDec() + Convertidor.binC2Int(linea.substring(8));
                Memoria.setDirActual(direccionDec);

                int trap = Convertidor.binInt(linea.substring(8));

                switch(trap)
                {
                    case 37:
                        while(espera) {

                        }
                        dR = 0;
                    break;
                    
                }

                
                
            break;
        }

        PanelMemoria.updateMemoria();
    }
}
